package com.zhi.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.zhi.config.Constant;
import com.zhi.entity.Student;
import com.zhi.entity.Teacher;
import com.zhi.service.StudentService;
import com.zhi.service.TeacherService;
import com.zhi.shiro.UserLoginToken;
import com.zhi.util.MD5Util;
import com.zhi.util.PubFun;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zhi.entity.User;
import com.zhi.service.LoginService;
import com.zhi.service.UserService;
import com.zhi.util.R;
import com.zhi.util.RandomValidateCodeUtil;

import java.util.List;

@Controller
public class LoginController {

    Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	UserService userService;

    @Autowired
    StudentService studentService;

    @Autowired
    TeacherService teacherService;
	
	@Autowired
	LoginService loginService;

    /**
     * 默认http://localhost:8081/，重定向登录
     * @return
     */
	@RequestMapping("/")
    public String toLogin() {
        return "redirect:/login";
    }

    /**
     * http://localhost:8081/login，跳转登录
     * @return
     */
	@RequestMapping("/login")
    public String login() {
        return "login/login";
    }

    /**
     * 注册页面跳转
     */
    @RequestMapping("/register")
    public String register(){ return "login/register";}
    /**
     * 登录校验
     * @param model
     * @param user
     * @param verify
     * @param session
     * @return
     */
    @PostMapping("/login")
    @ResponseBody
    public R loginSubmit(Model model,User user,String verify,HttpSession session) {
        
    	//从session中获取随机数
        String random = (String) session.getAttribute(RandomValidateCodeUtil.RANDOMCODEKEY);
        random = random==null?"":random;
        if (StringUtils.isEmpty(verify) || !random.equals(verify)) {
        	return R.error("请输入正确的验证码");
        }

        //密码MD5加密
        user.setPassword(MD5Util.md5Encryption(user.getPassword()));

        //登录信息
        String loginUsername = user.getUsername();
        String loginPassword = user.getPassword();
        String loginUserType = user.getUserType();

        logger.info("登录信息："+loginUsername+","+loginPassword+","+loginUserType);

        //使用shiro登录验证
        try {
            //1、实例化校验工具对象
			Subject subject = SecurityUtils.getSubject();

			//2实例化登录预想数据，不再使用原生类UsernamePasswordToken，使用自定义的UserLoginToken
            UserLoginToken token = new UserLoginToken(loginUsername,loginPassword,loginUserType);

            //3登录校验
			subject.login(token);

			//4若程序执行到这一步，说明用户登录检验通过，否则会抛出异常
            token.setRememberMe(true);//记住我

            //5在此判断登录的用户类型，并获取对应的个人信息
            String username = "";
            if(Constant.USER_TYPE_STUDENT.equals(loginUserType)){

                //1-学生,登录使用学号作为用户名，查询，放入session缓存
//                String studentId = loginUsername;
//                Student student = studentService.getOne(studentId);
//                username = student.getName();
//                session.setAttribute("sessionStudent",student);
                username = user.getUsername();

            }else if(Constant.USER_TYPE_TEACHER.equals(loginUserType)){

                //2-教师，登录使用工号作为用户名,查询，放入session缓存
                String teacherId = loginUsername;
                Teacher teacher = teacherService.getOne(teacherId);
                username = teacher.getName();
                session.setAttribute("sessionTeacher",teacher);

            }else if(Constant.USER_TYPE_ADMIN.equals(loginUserType)){

                //3-管理员
                //管理员只有user表，无其他逻辑
                username = user.getUsername();

            }else{
                return R.error("用户类型错误");
            }

            //6查询完整的user信息，包含id
			User u = userService.findAll(user).get(0);

            //7将登录用户信息存于session
            session.setAttribute("username",username);
			session.setAttribute("sessionUser",u);
			return R.ok();

		} catch (Exception e) {
			logger.error("账号密码不匹配");
			return R.error(e.getMessage());
		}
        
    }

    /**
     * 登录成功主界面
     * @param model
     * @param session
     * @return
     */
	@RequestMapping("/index")
    public String index(Model model,HttpSession session) {
		User user = (User)session.getAttribute("sessionUser");
		model.addAttribute("user", user);
		model.addAttribute("picUrl", "/img/photo_s.jpg");
		return "index";
    }

    /**
     * 正文首页页面
     * @return
     */
	@RequestMapping("/main")
    public String main() {
		return "public/main";
    }

    /**
     * 退出登录
     * @param session
     * @return
     */
	@RequestMapping("/logout")
    public String logout(HttpSession session) {

        //退出登录时，清空session中的用户信息
		session.removeAttribute("sessionUser");
        session.removeAttribute("sessionStudent");
        session.removeAttribute("sessionTeacher");
		return "redirect:/login";
    }
    
    //生成验证码
    @GetMapping(value = "/getVerify")
    public void getVerify(HttpServletRequest request, HttpServletResponse response) {
        try {
            response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
            response.setHeader("Pragma", "No-cache");//设置响应头信息，告诉浏览器不要缓存此内容
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expire", 0);
            RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();
            randomValidateCode.getRandcode(request, response);//输出验证码图片方法
        } catch (Exception e) {
            logger.error("获取验证码失败", e);
        }
    }

    /**
     * 用户信息修改
     * @param model
     * @param user
     * @param verify
     * @param session
     * @return
     */
    @PostMapping("/userinfo/update")
    @ResponseBody
    public R userUpdate(Model model, User user, HttpSession session) {




        //登录信息
        Integer loginUserId = user.getId();
        String loginUsername = user.getUsername();
        String loginPassword = user.getPassword();
        String loginUserType = user.getUserType();
        String loginUserSex = user.getUserSex();
        Integer loginUserAge = user.getUserAge();
        logger.info("登录信息："+loginUsername+","+loginPassword+","+loginUserType);
        if(PubFun.isNull(loginUserSex)){
            return R.error("未选择用户性别");
        }
        if(PubFun.isNull(loginPassword)){
            return R.error("未录入密码");
        }
        if(loginUserAge == null){
            return R.error("未录入用户年龄");
        }
        //密码MD5加密md5Encryption
        user.setPassword(MD5Util.md5Encryption(user.getPassword()));
        User user1 = userService.finByName(loginUsername);
        //判断数据库中是否存在此用户
        if(user1.getUsername().equals(loginUsername)&&(user1.getId() != loginUserId)){
             return R.error("用户名已经被占用，请更换其他用户名。");
        }
        user.setUserState(Constant.EFFECTIVE_YES);//设置了字段默认1-生效，但是报错，有空子再找原因
        try{
            userService.save(user);
            session.removeAttribute("username");
            session.removeAttribute("sessionUser");
            return R.ok();
        }catch (Exception e){
            return R.error("修改失败");
        }
    }


    @PostMapping("/register")
    @ResponseBody
    public R registerSubmit(Model model, User user, HttpSession session) {


        //密码MD5加密md5Encryption
        user.setPassword(MD5Util.md5Encryption(user.getPassword()));

        //登录信息
        String loginUsername = user.getUsername();
        String loginPassword = user.getPassword();
        String loginUserType = user.getUserType();
        String loginUserSex = user.getUserSex();
        Integer loginUserAge = user.getUserAge();
        logger.info("登录信息："+loginUsername+","+loginPassword+","+loginUserType);
        if(PubFun.isNull(loginUserSex)){
            return R.error("未选择用户性别");
        }
        if(loginUserAge == null){
            return R.error("未录入用户年龄");
        }
        User user1 = userService.finByName(loginUsername);
        //判断数据库中是否存在此用户
        if(user1 != null){
            return R.error("用户已存在，请直接登录");
        }
        user.setUserState(Constant.EFFECTIVE_YES);//设置了字段默认1-生效，但是报错，有空子再找原因
        //user.setPassword(MD5Util.md5Encryption(user.getPassword()));//密码MD5加密)
        try{
            userService.save(user);
            session.setAttribute("username",loginUsername);
            session.setAttribute("sessionUser",user);
            return R.ok();
        }catch (Exception e){
            return R.error("注册失败");
        }
    }
}
